package com.frogs.ucenter.component;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.frogs.api.wechat.util.TemplateUtil;
import com.frogs.framework.util.PageList;
import com.frogs.framework.util.StringUtil;
import com.frogs.framework.util.date.DateUtil;
import com.frogs.system.util.AttentionStateEnum;
import com.frogs.system.util.CouponTypeEnum;
import com.frogs.system.util.MessageActionKey;
import com.frogs.system.util.OpenPlatformEnum;
import com.frogs.system.util.OrderStatusEnum;
import com.frogs.system.util.TaskActionStatusEnum;
import com.frogs.system.util.TaskCompleteStatusEnum;
import com.frogs.system.util.TaskCycleEnum;
import com.frogs.system.util.TaskGetStrategyEnum;
import com.frogs.system.util.TaskGetTypeEnum;
import com.frogs.system.util.TaskTypeEnum;
import com.frogs.system.util.UserIntegralRecordEnum;
import com.frogs.system.web.api.entity.FeedsRecordActiveMqEntity;
import com.frogs.system.web.exception.ServiceOperationException;
import com.frogs.ucenter.dao.ActionLogDao;
import com.frogs.ucenter.dao.PointTaskCompleteInfoDao;
import com.frogs.ucenter.dao.TaskInfoDao;
import com.frogs.ucenter.dao.UserAttentionInfoDao;
import com.frogs.ucenter.dao.UserIntegralBalanceDao;
import com.frogs.ucenter.dao.UserIntegralRecordDao;
import com.frogs.ucenter.dao.UserOpenPlatformInfoDao;
import com.frogs.ucenter.dao.UserRechargeBalanceDao;
import com.frogs.ucenter.dao.UserRechargeRecordDao;
import com.frogs.ucenter.dao.WechatUserBaseInfoDao;
import com.frogs.ucenter.entity.GivingInfo;
import com.frogs.ucenter.entity.PointTaskCompleteInfo;
import com.frogs.ucenter.entity.TaskInfo;
import com.frogs.ucenter.entity.UserIntegralBalance;
import com.frogs.ucenter.entity.UserIntegralRecord;
import com.frogs.ucenter.entity.UserOpenPlatformInfo;
import com.frogs.ucenter.entity.UserRechargeBalance;
import com.frogs.ucenter.entity.UserRechargeRecord;
import com.frogs.ucenter.entity.WechatUserBaseInfo;
import com.frogs.ucenter.entity.ext.UserAttentionInfoExt;
import com.frogs.ucenter.util.Constants;
import com.frogs.ucenter.util.record.FeedsRecordActiveMqSend;
import com.frogs.ucenter.util.wechat.WechatMessageSend;

@Component("givingAsyncHelper")
public class GivingAsyncHelper extends RequestApiHelper {

	private static Logger log = LoggerFactory.getLogger(GivingAsyncHelper.class);
	
	@Resource
	private UserRechargeRecordDao userRechargeRecordDao;
	@Resource
	private UserRechargeBalanceDao userRechargeBalanceDao;
	@Resource
	private UserIntegralRecordDao userIntegralRecordDao;
	@Resource
	private UserIntegralBalanceDao userIntegralBalanceDao;
	@Resource
	private TaskInfoDao taskInfoDao;
	@Resource
	private PointTaskCompleteInfoDao pointTaskCompleteInfoDao;
	@Resource
	private ActionLogDao actionLogDao;
	@Resource
	private UserOpenPlatformInfoDao userOpenPlatformInfoDao;
	@Resource
	private WechatUserBaseInfoDao wechatUserBaseInfoDao;
	@Resource
	private WechatMessageSend wechatMessageSend;
	@Resource
	private FeedsRecordActiveMqSend feedsRecordActiveMqSend;
	@Resource
	private UserAttentionInfoDao userAttentionDao;
	
	@Async
	public void giving(GivingInfo givingInfo) {
		try {
			log.info("func[giving] givingInfo[" + JSONObject.toJSONString(givingInfo) + "] desc[giving before]");
			// 赠送金额
			if (givingInfo.getGiveMoney().compareTo(new BigDecimal("0.00")) == 1) {
				this.giveMoney(givingInfo.getUserId(), givingInfo.getGiveMoney());
			}
			// 赠送积分
			if (givingInfo.getGivePoint() != null && givingInfo.getGivePoint() > 0) {
				this.givePoint(givingInfo.getUserId(), givingInfo.getGivePoint(), givingInfo.getExpandCode()
						, givingInfo.getOpenPlatformId(),givingInfo.getTitle());
			}
			// 赠送优惠券
			if (givingInfo.getGiveCardId() != null && givingInfo.getGiveCardId() > 0) {
				if (givingInfo.getCardType() == CouponTypeEnum.IS_FALSE.getId()) {
					this.giveCard(givingInfo.getUserId(), givingInfo.getGiveCardId());
				}
			}
			// 赠送微信红包
			if (givingInfo.getGiveRedPacketId() != null && givingInfo.getGiveRedPacketId() > 0) {
				//TODO 暂时写死一个公众号的用户
				Map<String, Object> params = new HashMap<String, Object>();
				params.put("eqUserId", givingInfo.getUserId());
				params.put("eqOpenPlatformId", givingInfo.getOpenPlatformId());
				PageList<UserOpenPlatformInfo> list = userOpenPlatformInfoDao.selectByMap(params, false);
				if (list.size() > 0) {
					UserOpenPlatformInfo openPlatformInfo = list.get(0);
					String openId = openPlatformInfo.getOpenId();
					this.giveRedPack(openId, givingInfo.getGiveRedPacketId());
				}
			}
		} catch(Exception e) {
			log.error("func[{}] givingInfo[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						JSON.toJSONString(givingInfo), e.getMessage(),Arrays.deepToString(e.getStackTrace()) });
		}
	}
	
	private void giveMoney(Integer userId, BigDecimal giveMoney) {
		// 插入赠送记录
		UserRechargeRecord userRechargeRecord = new UserRechargeRecord();
		userRechargeRecord.setRechargeCard("");
		userRechargeRecord.setRechargeFrom("任务赠送");
		userRechargeRecord.setRechargeMoney(giveMoney);
		userRechargeRecord.setUserId(userId);
		userRechargeRecord.setStatus(OrderStatusEnum.ORDER_STATUS_YES.getId());
		userRechargeRecordDao.insert(userRechargeRecord);
		// 更新用户余额账户
		log.info("func[giveMoney] giveMoney[" + giveMoney + "] userId[" + userId + "] desc[update balance before]");
		UserRechargeBalance userRechargeBalance = userRechargeBalanceDao.selectById(userId);
		if (userRechargeBalance != null) {
			BigDecimal balance = userRechargeBalance.getBalance();
			String encryptBalance = userRechargeBalance.getEncryptBalance();
			if (StringUtil.md5(userId + balance.toString(), Constants.ENCRYPT_BALABCE_KEY).equals(encryptBalance)) {
				userRechargeBalance.setBalance(balance.add(giveMoney).setScale(2, BigDecimal.ROUND_HALF_UP));
				userRechargeBalance.setEncryptBalance(StringUtil.md5(userId + balance.add(giveMoney).setScale(2, BigDecimal.ROUND_HALF_UP).toString(), Constants.ENCRYPT_BALABCE_KEY));
				userRechargeBalance.setUpdateDate(new Date());
				userRechargeBalanceDao.update(userRechargeBalance);
			} else {
				log.error("func[giveMoney] userId[" + userId + "] balance[" + balance + "] desc[旧的余额有误]");
			}
		} else {
			userRechargeBalance = new UserRechargeBalance();
			userRechargeBalance.setId(userId);
			userRechargeBalance.setBalance(giveMoney.setScale(2, BigDecimal.ROUND_HALF_UP));
			userRechargeBalance.setEncryptBalance(StringUtil.md5(userId + giveMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString(), Constants.ENCRYPT_BALABCE_KEY));
			userRechargeBalanceDao.insert(userRechargeBalance);
		}
		log.info("func[giveMoney] giveMoney[" + giveMoney + "] userId[" + userId + "] desc[update balance end]");
	}
	
	private void givePoint(Integer userId, Integer givePoint, String expandCode, Integer applicablePlatformId,String title) {
		UserIntegralRecord userIntegralRecord = new UserIntegralRecord();
		String taskTitle = "完成"+title+"任务送哇币";
		userIntegralRecord.setIntegralNum(givePoint);
		userIntegralRecord.setType(UserIntegralRecordEnum.TASKCOMPLETE_DONATE.getId());
		userIntegralRecord.setUserId(userId);
		userIntegralRecord.setRemark(taskTitle);
		userIntegralRecord.setExpandCode(expandCode);
		userIntegralRecord.setApplicablePlatformId(applicablePlatformId);
		userIntegralRecordDao.insert(userIntegralRecord);
		log.info("func[givePoint] givePoint[" + givePoint + "] userId[" + userId + "] desc[update integral before]");
		UserIntegralBalance userIntegralBalance = userIntegralBalanceDao.selectById(userId);
		if(null == userIntegralBalance){//不存在则进行插入操作
			userIntegralBalance = new UserIntegralBalance();
			userIntegralBalance.setIntegralUsable(givePoint);
			userIntegralBalance.setIntegralUsed(0);
			userIntegralBalance.setId(userId);
			userIntegralBalanceDao.insert(userIntegralBalance);
		}else{//存在则进行更新操作
			int integralUsable = userIntegralBalance.getIntegralUsable();
			userIntegralBalance = new UserIntegralBalance();
			userIntegralBalance.setId(userId);
			userIntegralBalance.setIntegralUsable(integralUsable + givePoint);
			userIntegralBalanceDao.update(userIntegralBalance);
		}
		
		
		//TODO 对于具体测量项目，以后完善
		String actionRecord = "realName完成"+title+"任务，获得"+givePoint+"个哇币！"; 
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqWechatApplicationId", OpenPlatformEnum.WECHAT_HDC.getId());
		params.put("eqUserId", userId);
		
		PageList<WechatUserBaseInfo> list = wechatUserBaseInfoDao.selectByMap(params , 1 , 1, false);
		
		insertUserFeedsRecord(userId,actionRecord,list.get(0).getNickName());
		log.info("func[givePoint] givePoint[" + givePoint + "] userId[" + userId + "] desc[update integral end]");
	}
	
	/**
	 * 自动更新任务
	 * 
	 * @param actionType
	 * @param userId
	 * @throws Exception
	 */
	@Async
	public void autoUpdateTask(String actionType, Integer userId, Integer openPlatformId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqActionType", actionType);
		params.put("eqTaskType", TaskTypeEnum.POINTTASK.getId());
		params.put("eqStatus", TaskActionStatusEnum.ENABLED.getId());
		params.put("leStartTime", new Date());
		params.put("geEndTime", new Date());
		params.put("eqOpenPlatformId", openPlatformId);
		PageList<TaskInfo> list = taskInfoDao.selectByMap(params, false);
		for (TaskInfo taskInfo : list) {
			Integer cycle = taskInfo.getCycle();
			if (taskInfo.getGetStrategy() == TaskGetStrategyEnum.LIMITED.getId() && taskInfo.getGetNum() == 0) {
				continue;
			}
			log.info("func[autoCompleteTask] cycle[{"+cycle+"}] desc[获取周期]");
			if (cycle == TaskCycleEnum.ONCE.getId()) {
				this.completePointByOnce(taskInfo, userId);
			} else if (cycle == TaskCycleEnum.EVERYDAY.getId()) {
				this.completePointByEveryDay(taskInfo, userId);
			} else if (cycle == TaskCycleEnum.NOCODITION.getId()) {
				this.completePointByNoCondition(taskInfo, userId);
			} else if (cycle == TaskCycleEnum.WEEKLY.getId()) {
				this.completePointByWeekly(taskInfo, userId);
			} else if (cycle == TaskCycleEnum.MONTHLY.getId()) {
				this.completePointByMonthly(taskInfo, userId);
			} else if (cycle == TaskCycleEnum.CONTINUOUS.getId()) {
				this.completePointByContinuous(taskInfo, userId);
			}
		}
	}
	
	private void completePointByOnce(TaskInfo taskInfo, Integer userId) throws Exception  {
		Map<String, Object> params = new HashMap<String, Object>();
		String actionType = taskInfo.getActionType();
		Integer completeNum = taskInfo.getCompleteNum();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		params.put("eqTaskId", taskInfo.getId());
		params.put("eqUserId", userId);
		PageList<PointTaskCompleteInfo> list = pointTaskCompleteInfoDao.selectByMap(params, false);
		PointTaskCompleteInfo completeInfo = new PointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId() 
					|| completeInfo.getStatus() == TaskCompleteStatusEnum.FINISH.getId()) {
				return;
			}
		}
		params.clear();
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		params.put("eqActionType", actionType);
		params.put("eqUserId", userId);
		params.put("gtCreateTime", taskInfo.getStartTime());
		params.put("leCreateTime", taskInfo.getEndTime());
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		if (count < completeNum) {
			updatePointTask(completeInfo.getId(), count);
		} else {
			// 更新该常规任务
			updatePointTask(userId, completeInfo, taskInfo);
		}
	}
	
	private void updateTask(PointTaskCompleteInfo completeInfo, TaskInfo taskInfo, Integer userId, Integer count) throws Exception {
		Integer numberUpperLimit = taskInfo.getNumberUpperLimit();
		Integer completeNum = taskInfo.getCompleteNum();
		if (completeInfo.getStatus() != TaskCompleteStatusEnum.COMPLETED.getId()) {
			if (completeInfo.getNumberUpperLimit() > 0) {
				Integer leftNum = numberUpperLimit - completeInfo.getNumberUpperLimit();
				if ((count - leftNum*completeNum) >=completeNum) {
					// 更新该常规任务
					updatePointTask(userId, completeInfo, taskInfo);
					count = count -completeNum;
				} else {
					Integer num = (count - leftNum*completeNum) <= 0 ? 0 : (count - leftNum*completeNum); 
					updatePointTask(completeInfo.getId(), num);
				}
			}
		}
	}
	
	private void completePointByEveryDay(TaskInfo taskInfo, Integer userId)  throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		String actionType = taskInfo.getActionType();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		
		params.put("eqTaskId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("gtCreateTime", DateUtil.formatDate(new Date(), "yyyy-MM-dd"));
		PageList<PointTaskCompleteInfo> list = pointTaskCompleteInfoDao.selectByMap(params, false);
		PointTaskCompleteInfo completeInfo = new PointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId() 
					|| completeInfo.getStatus() == TaskCompleteStatusEnum.FINISH.getId()) {
				return;
			}
		}
		params.clear();
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		params.put("eqActionType", actionType);
		params.put("eqUserId", userId);
		params.put("gtCreateTime", DateUtil.formatDate(new Date(), "yyyy-MM-dd"));
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		Integer count = actionLogDao.selectCountByMap(params);
		this.updateTask(completeInfo, taskInfo, userId, count);
	}
	
	private void completePointByNoCondition(TaskInfo taskInfo, Integer userId)  throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		String actionType = taskInfo.getActionType();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		params.put("eqTaskId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("gtCreateTime", taskInfo.getStartTime());
		params.put("leCreateTime", taskInfo.getEndTime());
		PageList<PointTaskCompleteInfo> list = pointTaskCompleteInfoDao.selectByMap(params, false);
		PointTaskCompleteInfo completeInfo = new PointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId() 
					|| completeInfo.getStatus() == TaskCompleteStatusEnum.FINISH.getId()) {
				return;
			}
		}
		params.clear();
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		params.put("eqActionType", actionType);
		params.put("eqUserId", userId);
		params.put("gtCreateTime", taskInfo.getStartTime());
		params.put("leCreateTime", taskInfo.getEndTime());
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		this.updateTask(completeInfo, taskInfo, userId, count);
	}
	
	private void completePointByWeekly(TaskInfo taskInfo, Integer userId)  throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		String actionType = taskInfo.getActionType();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		String firstDay = DateUtil.formatDate(DateUtil.getFirstDayOfWeek(), "yyyy-MM-dd");
		String endDay = DateUtil.formatDate(DateUtil.getDateAfterDays(DateUtil.getFirstDayOfWeek(), 7), "yyyy-MM-dd");
		params.put("eqTaskId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("gtCreateTime", firstDay);
		params.put("ltCreateTime", endDay);
		PageList<PointTaskCompleteInfo> list = pointTaskCompleteInfoDao.selectByMap(params, false);
		PointTaskCompleteInfo completeInfo = new PointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId() 
					|| completeInfo.getStatus() == TaskCompleteStatusEnum.FINISH.getId()) {
				return;
			}
		}
		params.clear();
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		params.put("eqActionType", actionType);
		params.put("eqUserId", userId);
		params.put("gtCreateTime", firstDay);
		params.put("ltCreateTime", endDay);
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		this.updateTask(completeInfo, taskInfo, userId, count);
	}
	
	private void completePointByMonthly(TaskInfo taskInfo, Integer userId) throws Exception  {
		Map<String, Object> params = new HashMap<String, Object>();
		String actionType = taskInfo.getActionType();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		String firstDay = DateUtil.formatDate(DateUtil.getFirstDayOfMonth(), "yyyy-MM-dd");
		String endDay = DateUtil.formatDate(DateUtil.getDateAfterDays(DateUtil.getLastDayOfMonth(), 1), "yyyy-MM-dd");
		params.put("eqTaskId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("gtCreateTime", firstDay);
		params.put("ltCreateTime", endDay);
		PageList<PointTaskCompleteInfo> list = pointTaskCompleteInfoDao.selectByMap(params, false);
		PointTaskCompleteInfo completeInfo = new PointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId() 
					|| completeInfo.getStatus() == TaskCompleteStatusEnum.FINISH.getId()) {
				return;
			}
		}
		params.clear();
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		params.put("eqActionType", actionType);
		params.put("eqUserId", userId);
		params.put("gtCreateTime", firstDay);
		params.put("ltCreateTime", endDay);
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		this.updateTask(completeInfo, taskInfo, userId, count);
	}
	
	private void updatePointTask(Integer id, Integer completeNum) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", id);
		params.put("eqStatus", TaskCompleteStatusEnum.PROCESSING.getId());
		params.put("completeNum", completeNum);
		int count = pointTaskCompleteInfoDao.updateByMap(params);
		if (count < 1) {
			throw new ServiceOperationException("更新任务失败");
		}
	}
	
	/**
	 * 更新常规任务
	 */
	private void updatePointTask(Integer userId, PointTaskCompleteInfo completeInfo, TaskInfo taskInfo)  throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", completeInfo.getId());
		params.put("neStatus", TaskCompleteStatusEnum.COMPLETED.getId());
		if (taskInfo.getGetType() == TaskGetTypeEnum.AUTO.getId()) {
			if ((completeInfo.getNumberUpperLimit()-1) > 0) {
				params.put("status", TaskCompleteStatusEnum.PROCESSING.getId());
				params.put("completeNum", 0);
			} else {
				params.put("status", TaskCompleteStatusEnum.COMPLETED.getId());
				params.put("completeNum", taskInfo.getCompleteNum());
			}
			params.put("numberUpperLimit", completeInfo.getNumberUpperLimit()-1);
		} else {
			params.put("status", TaskCompleteStatusEnum.FINISH.getId());
			params.put("completeNum", taskInfo.getCompleteNum());
		}
		int count = pointTaskCompleteInfoDao.updateByMap(params);
		if (count < 1) {
			throw new ServiceOperationException("更新任务失败");
		}
		if (taskInfo.getGetType() == TaskGetTypeEnum.AUTO.getId()) { //自动领取
			if (taskInfo.getGetStrategy() == TaskGetStrategyEnum.LIMITED.getId()) {
				taskInfo.setGetNum(taskInfo.getGetNum()-1);
				if ((taskInfo.getGetNum()-1) == 0) {
					taskInfo.setStatus(TaskActionStatusEnum.DELETED.getId());
				}
				taskInfoDao.update(taskInfo);
			}
			// 赠送
			GivingInfo givingInfo = setGivingInfo(taskInfo, userId);
			this.giving(givingInfo);
			//发送领取奖励信息
			this.sendRewardsMessage(taskInfo, userId);
		} else {
			//发送待领取提醒，链接跳过去领取
			this.sendCompleteTaskMessage(taskInfo, userId);
		}
	}
	
	//TODO 文案可以在讨论
	private void sendRewardsMessage(TaskInfo taskInfo, Integer userId) {
		try {
			Integer point = taskInfo.getGivePoint();
			String url = "";
			if (point > 0) {
				//
				url = "http://w.frogshealth.com/user/nologin/url.html?acType="+MessageActionKey.TASK_COMPLETE_LOG.getId();
			}
			String keyword = "任务奖励通知";
			String messageStr = TemplateUtil.convert(url, keyword, taskInfo.getMessageTemplate());
			Integer openPlatformId = taskInfo.getOpenPlatformId();
			wechatMessageSend.send(userId, userId, messageStr, openPlatformId);
		
		} catch (Exception e) {
			log.error("func[{}] taskInfo[{}] userId[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						JSON.toJSONString(taskInfo), userId, e.getMessage(),Arrays.deepToString(e.getStackTrace()) });
		}
	}
	
	//TODO 文案可以再讨论
	private void sendCompleteTaskMessage(TaskInfo taskInfo, Integer userId) {
		try {
			String url = "https://open.weixin.qq.com/connect/oauth2/authorize?&redirect_uri=http%3A%2F%2Fw.frogshealth.com%2Fuser%2Ftask%2Findex.html%3facType%3d"+MessageActionKey.TASK_COMPLETE_LOG.getId()+"&appid=wxb30222354415be84&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
			String keyword = "完成任务通知";
			String messageStr = TemplateUtil.convert(url, keyword, taskInfo.getMessageTemplate());
			Integer openPlatformId = taskInfo.getOpenPlatformId();
			wechatMessageSend.send(userId, userId, messageStr, openPlatformId);
		} catch (Exception e) {
			log.error("func[{}] taskInfo[{}] userId[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						JSON.toJSONString(taskInfo), userId, e.getMessage(),Arrays.deepToString(e.getStackTrace()) });
		}
	}
	
	public GivingInfo setGivingInfo(TaskInfo taskInfo, Integer userId) {
		GivingInfo givingInfo = new GivingInfo();
		givingInfo.setApplicablePlatformId(taskInfo.getApplicablePlatformId());
		givingInfo.setCardType(taskInfo.getCardType());
		givingInfo.setExpandCode(taskInfo.getExpandCode());
		givingInfo.setGiveCardId(taskInfo.getGiveCardId());
		givingInfo.setGiveMoney(taskInfo.getGiveMoney());
		givingInfo.setGivePoint(taskInfo.getGivePoint());
		givingInfo.setGiveRedPacketId(taskInfo.getGiveRedPacketId());
		givingInfo.setOpenPlatformId(taskInfo.getOpenPlatformId());
		givingInfo.setUserId(userId);
		givingInfo.setTitle(taskInfo.getTitle()); 
		return givingInfo;
	}
	
	/**
	 * 插入常规任务
	 * 
	 * @param taskInfo
	 * @param userId
	 * @throws Exception 
	 */
	private PointTaskCompleteInfo insertPointTask(TaskInfo taskInfo, Integer userId) throws Exception {
		PointTaskCompleteInfo pointTaskCompleteInfo = new PointTaskCompleteInfo();
		Date date = new Date();
		pointTaskCompleteInfo.setCreateTime(date);
		pointTaskCompleteInfo.setTaskId(taskInfo.getId());
		pointTaskCompleteInfo.setUserId(userId);
		pointTaskCompleteInfo.setLastDate(date);
		pointTaskCompleteInfo.setStatus(TaskCompleteStatusEnum.PROCESSING.getId());
		pointTaskCompleteInfo.setCompleteNum(0);
		pointTaskCompleteInfo.setNumberUpperLimit(taskInfo.getNumberUpperLimit());
		pointTaskCompleteInfoDao.insert(pointTaskCompleteInfo);
		return pointTaskCompleteInfo;
	}
	
	/**
	 * 连续执行任务
	 */
	public void completePointByContinuous(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		Integer completeNum = taskInfo.getCompleteNum();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		Integer days = taskInfo.getDays();
		params.put("eqTaskId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("orderByClause", "id desc");
		PageList<PointTaskCompleteInfo> listPointTaskCompleteInfos = pointTaskCompleteInfoDao.selectByMap(params, false);
		PointTaskCompleteInfo completeInfo = new PointTaskCompleteInfo();
		if (listPointTaskCompleteInfos.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = listPointTaskCompleteInfos.get(0);
		}
		if (completeInfo.getStatus() != TaskCompleteStatusEnum.FINISH.getId()) {
			if (completeInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
				if (DateUtil.formatDate(new Date(), "yyyy-MM-dd").equals(DateUtil.formatDate(completeInfo.getLastDate(), "yyyy-MM-dd"))) {
					return;
				} else {
					completeInfo = insertPointTask(taskInfo, userId);
				}
			}
			
			params.clear();
			params.put("eqActionType", taskInfo.getActionType());
			params.put("eqUserId", userId);
			params.put("gtCreateTime", DateUtil.formatDate(new Date(), "yyyy-MM-dd"));
			if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
				params.put("geMoney", completeMoney);
			}
			int count = actionLogDao.selectCountByMap(params);
			log.info("func[completePointByContinuous] actionLog count = " + count + "completeNum = " + completeNum);
			if (count < completeNum) {
				return;
			}
			if (completeInfo.getLastDate().getTime() != completeInfo.getCreateTime().getTime()) {
				log.info("func[completePointByContinuous] updatePointTask 1");
				if (DateUtil.formatDate(new Date(), "yyyy-MM-dd").equals(DateUtil.formatDate(DateUtil.getDateAfterDays(completeInfo.getLastDate(), 1), "yyyy-MM-dd"))) {
					log.info("func[completePointByContinuous] updatePointTask 2");
					if ((completeInfo.getCompleteDays() + 1) == days) {
						log.info("func[completePointByContinuous] updatePointTask 3");
						updatePointTaskByContinuouus(userId, completeInfo.getId(), taskInfo);
					} else {
						log.info("func[completePointByContinuous] updatePointTask 4");
						updatePointTask(userId, completeInfo.getId(), taskInfo, completeInfo.getCompleteDays() + 1);
					}
				} else if (!DateUtil.formatDate(new Date(), "yyyy-MM-dd").equals(DateUtil.formatDate(completeInfo.getLastDate(), "yyyy-MM-dd"))) {
					log.info("func[completePointByContinuous] updatePointTask 5");
					updatePointTask(userId, completeInfo.getId(), taskInfo, 1);
				}
				log.info("func[completePointByContinuous] updatePointTask 6");
			} else {
				log.info("func[completePointByContinuous] updatePointTask 7");
				updatePointTask(userId, completeInfo.getId(), taskInfo, 1);
			}
		}
	}
	
	/**
	 * 更新常规任务
	 * 
	 * @param taskCompleteId
	 */
	private void updatePointTask(Integer userId, Integer taskCompleteInfoId, TaskInfo taskInfo, Integer completeDays)  throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskCompleteInfoId);
		params.put("neStatus", TaskCompleteStatusEnum.COMPLETED.getId());
		params.put("lastDate", new Date());
		params.put("completeDays", completeDays);
		int count = pointTaskCompleteInfoDao.updateByMap(params);
		if (count < 1) {
			throw new ServiceOperationException("更新任务失败");
		}
	}
	
	/**
	 * 更新常规任务
	 * 
	 * @param taskCompleteId
	 */
	private void updatePointTaskByContinuouus(Integer userId, Integer taskCompleteInfoId, TaskInfo taskInfo)  throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskCompleteInfoId);
		params.put("neStatus", TaskCompleteStatusEnum.COMPLETED.getId());
		params.put("status", TaskCompleteStatusEnum.FINISH.getId());
		params.put("completeDays", taskInfo.getDays());
		params.put("lastDate", new Date());
		int count = pointTaskCompleteInfoDao.updateByMap(params);
		if (count < 1) {
			throw new ServiceOperationException("更新任务失败");
		}
	}
	
	/**
	 * 记录用户行为
	 * @param userId
	 * @param actionRecord
	 */
	private void insertUserFeedsRecord(int userId,String actionRecord,String ownName) {
		try {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("eqFollowedUserId", userId);
			params.put("eqStatus", AttentionStateEnum.ATTENTION_STATUS_AGREED.getId());
			params.put("eqOpenPlatformId", OpenPlatformEnum.WECHAT_HDC.getId());
			List<UserAttentionInfoExt> list = userAttentionDao.selectByMapForAttention(params,0,1000); 
			String copyActionRecord = actionRecord;
			
			FeedsRecordActiveMqEntity feedsRecordActiveMqEntity = new FeedsRecordActiveMqEntity();
			feedsRecordActiveMqEntity.setFollowedUserId(userId);
			feedsRecordActiveMqEntity.setMessage("");      //点赞接口要改，改后在修改
			feedsRecordActiveMqEntity.setType(0); 
			
			
			for (UserAttentionInfoExt userAttentionInfoExt : list) {
				actionRecord = actionRecord.replace("realName", StringUtil.isEmpty(userAttentionInfoExt.getRealName())?ownName:userAttentionInfoExt.getRealName());
				FeedsRecordActiveMqEntity feedsRecordActiveMqEntityCopy = new FeedsRecordActiveMqEntity();
				BeanUtils.copyProperties(feedsRecordActiveMqEntityCopy,feedsRecordActiveMqEntity);  
				
				feedsRecordActiveMqEntityCopy.setFamilyId(userAttentionInfoExt.getFamilyId());
				feedsRecordActiveMqEntityCopy.setFollowUserId(userAttentionInfoExt.getFollowUserId());
				feedsRecordActiveMqEntityCopy.setActionRecord(actionRecord);
				log.info("发送到activeMq队列的数据："+JSON.toJSONString(feedsRecordActiveMqEntityCopy));  
				feedsRecordActiveMqSend.sendToQueue(feedsRecordActiveMqEntityCopy);
				actionRecord = copyActionRecord;
			}
			
		} catch (Exception e) {
			log.error("func[{}] params[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						"动作发起用户id："+userId+"动作记录："+actionRecord, e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
		
	}
	
}
